function [ID,Pars] = C_createNI(varargin)
%% Setup NI Acquisition Session

global CG; 

%% CHECK FOR LAST SESSION ID
ID = C_getModuleID('ModuleType','NI');

%% PARSE INITIALIZATION ARGUMENTS
P = parsePairs(varargin);
% PARAMETERS
[Pars,P] = C_getParametersModule('ModuleType','NI','IDType',ID,'Pars',P);
% OPTIONS
checkField(P,'Name',['NI',num2str(ID)]);
checkField(P,'Start',0);
checkField(P,'Reset',0);

%% DISCOVER AVAILABLE BOARDS
C_discoverNI;
 %daq.HardwareInfo.getInstance('DisableReferenceClockSynchronization',true);

%% SETUP ANALOG INPUT SESSION
CG.Sessions.NI(ID).Name  = P.Name;
CG.Sessions.NI(ID).Device  = P.Device;
CG.Sessions.NI(ID).SAI = daq.createSession('ni');
CG.Sessions.NI(ID).SAI.IsContinuous = true;
CG.Sessions.NI(ID).SAI. ExternalTriggerTimeout = 1000; % WAIT FOR A LOOOOONG TIME UNTIL THE TRIGGER COMES
CG.Sessions.NI(ID).NAnalogIn = 0;
CG.Sessions.NI(ID).NAnalogOut = 0;
CG.Sessions.NI(ID).NDigitalOut = 0;
CG.Sessions.NI(ID).Saving = P.Saving;
C_setSRNI(ID,P.SRAI,'SAI');

% INITIALIZE BASIC VARIABLES
CG.Display.NI(ID).DisplayDuration = P.DisplayDuration;
CG.Display.NI(ID).State = 0;
CG.Display.NI(ID).FIG = [];
CG.Display.NI(ID).PacketsAcquired = 0;
CG.Data.NI(ID) = struct('Analog',single([]),'Time',double([]));

% ADD ANALOG INPUT CHANNELS
if ~isempty(P.ChAI)
  C_addChannelsNI(ID,'ChannelType','AI','Channels',P.ChAI,...
    'Threshold',NaN,'TerminalConfig',P.TerminalConfig,'Names',P.AINames);
end

% SETUP INPUT CALLBACK FUNCTION
ControlSamples = lower(P.SRAI * P.ControlInterval);
CG.Sessions.NI(ID).ControlSamples = ControlSamples;
CG.Sessions.NI(ID).SAI.NotifyWhenDataAvailableExceeds = ControlSamples;
CG.Sessions.NI(ID).CallbackAvail =  ...
  addlistener(CG.Sessions.NI(ID).SAI,'DataAvailable',@(src,evt)C_callbackNIIn(src,evt,ID));

%% SETUP ANALOG OUTPUT SESSION
CG.Sessions.NI(ID).SAO = daq.createSession('ni');
CG.Sessions.NI(ID).SAO.ExternalTriggerTimeout = 1000;
C_setSRNI(ID,P.SRAO,'SAO');
  
if ~isempty(P.ChAO)
  % ADD ANALOG OUTPUT CHANNELS
  C_addChannelsNI(ID,'ChannelType','AO','Channels',P.ChAO);
end

%% SETUP DIGITAL SESSION
CG.Sessions.NI(ID).SD = daq.createSession('ni');
    
if ~isempty(P.ChDO)
  % ADD DIGITAL OUTPUT CHANNELS
  C_addChannelsNI(ID,'ChannelType','DO','Channels',P.ChDO);
end

%% PREPARE OUTPUTs
C_prepareNIDisplay(ID);

%% START AUDIO
if P.Start C_startNI(ID); end